#ifndef _RTSPCLIENT_H_
#define _RTSPCLIENT_H_

#include <string>
#include <thread>
#include <functional>

extern "C" {
    #include "libavcodec/avcodec.h"
    #include "libavformat/avformat.h"
}

namespace simplemedia
{

    #define DEFAULT_RTSP_URL "rtsp://127.0.0.1:554/main"

    typedef struct RTSPMediaClientResolution
    {
        unsigned int horizontal;
        unsigned int vertical;
        unsigned int numerator;
        unsigned int denominator;

        RTSPMediaClientResolution()
            : horizontal(0)
            , vertical(0)
            , numerator(0)
            , denominator(0)
        {}
    } RTSPMediaClientResolution_t;

    enum RTSPMediaClientTransportMethod {
        RTSPMEDIACLIENT_TRANSPORT_TCP,
        RTSPMEDIACLIENT_TRANSPORT_UDP,
        RTSPMEDIACLIENT_TRANSPORT_RTP,
    };

    typedef std::function<void (bool, const RTSPMediaClientResolution_t &)> RTSPMediaClientStatusUpdateHandleCb;
    typedef std::function<void (int, uint8_t *, bool)> RTSPMediaClientDataReceiveCb;

    class RTSPMediaClient
    {
    public:
        RTSPMediaClient();
        ~RTSPMediaClient();

        int Start(const std::string &source = DEFAULT_RTSP_URL);

        void Stop();

        void DataReceiveRegister(RTSPMediaClientDataReceiveCb cb);

        void StatusUpdateHandleRegister(RTSPMediaClientStatusUpdateHandleCb cb);

        void OptionConfigTimeout(unsigned int us);
        void OptionConfigMaxdelay(unsigned int us);
        void OptionConfigTransportMethod(RTSPMediaClientTransportMethod method);

    private:
        void LoopthreadHandle();

    private:
        std::string source_;
        std::thread *loopthread_;
        bool stoploop_;
        bool runstate_;
        RTSPMediaClientDataReceiveCb on_data_receive_;
        RTSPMediaClientStatusUpdateHandleCb stream_status_update_handle_;

        AVFormatContext *format_ctx_;
        AVDictionary *format_opts_;
        AVCodecContext *avctx_;
        AVPacket *packet_;

        /* av_dict_set parameters */
        unsigned int timeout_;
        unsigned int maxdelay_;
        RTSPMediaClientTransportMethod transportmethod_;
    };

} // namespace simplemedia

#endif // _RTSPCLIENT_H_
